package com.asia.order.utils;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

/* 集合操作常用方法类.
 * <p>
 *
 * @author 柯
 */
public class ListUtil {

    /**
     * 判断List不为空,非空返回true,空则返回false
     *
     * @param list
     * @return boolean
     */
    public static boolean isNotNull(List<?> list) {

        if (null != list) {
            if ((list.size() > 0) && !list.isEmpty()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断List是为空,为空返回true,非空则返回false
     *
     * @param list
     * @return boolean
     */
    public static boolean isNull(List<?> list) {

        if (null == list || list.size() == 0 || list.isEmpty()) {
            return true;
        }
        return false;
    }

    /**
     * 
     * @Title: removeDuplist @date 2016年7月17日 下午3:55:38 @Description:
     * 去除集合中重复的内容 @param list @return @throws
     */
    public static List<String> removeDuplist(List<String> list) {
        if (list != null && list.size() > 0) {
            HashSet<String> hashSet = new HashSet<String>(list);
            list.clear();
            list.addAll(hashSet);
        }
        return list;
    }

    /**
     * 
     * @Title: removeDuplistInt @date 2016年7月18日 下午5:16:04 @Description:
     * 去除重复的值 @param list @return @throws
     */
    public static List<Integer> removeDuplistInt(List<Integer> list) {
        if (list != null && list.size() > 0) {
            HashSet<Integer> hashSet = new HashSet<Integer>(list);
            list.clear();
            list.addAll(hashSet);
        }
        return list;
    }

    /**
     * 
     * @Title: getCurveValue @date 2016年8月16日 下午4:48:33 @Description:
     * 计算集合中的最大值和最小值， 返回改后的最大值，间隔，最小值 @param list @return @throws
     */
    public static List<Long> getCurveValue(List<Long> list) {
        List<Long> curveList = new ArrayList<Long>();

        Long maxValue = 0l;// 集合中最大值
        Long avgValue = 0l;// 间隔值
        Long minValue = 0l;// 最小值

        if (ListUtil.isNotNull(list)) {
            maxValue = Collections.max(list) / 100;
        }

        if (maxValue > 10000) {
            maxValue += 1000;
        } else if (maxValue > 1000) {
            maxValue += 300;
        } else if (maxValue > 100) {
            maxValue += 50;
        } else if (maxValue > 10) {
            maxValue += 5;
        } else {
            maxValue = 10l;
        }

        avgValue = maxValue / 5;

        curveList.add(maxValue);
        curveList.add(avgValue);
        curveList.add(minValue);

        return curveList;
    }


    /**
     * list集合深度复制
     * @param src
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {  
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
        ObjectOutputStream out = new ObjectOutputStream(byteOut);  
        out.writeObject(src);  
      
        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());  
        ObjectInputStream in = new ObjectInputStream(byteIn);  
        @SuppressWarnings("unchecked")  
        List<T> dest = (List<T>) in.readObject();  
        return dest;  
    }  
    
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        for (int i = 0 ; i < 19; i++) {
            list.add("aa" + i);
        }
        int d = list.size() / 13;
        int q = list.size() % 13;
        if (q > 0) 
            d += 1;
        
        List<List<String>> datas = new ArrayList<List<String>>(d);
        if (d == 1) {
            datas.add(list);
        } else if (d > 1){
            for (int k = 0; k < d; k ++) {
                List<String> sub_a = new ArrayList<String>();
                if (k == d - 1)
                    sub_a = list.subList(k * 13, list.size());
                else 
                    sub_a = list.subList(k * 13, (k + 1) * 13);
                
                datas.add(sub_a);
            }
        }
        
        System.out.println(d);
        for (List<String> obj : datas) {
            List<String> data =  obj;
            for (String c : data) {
                System.out.println(c);
            }
        }
    }


    /**
     *对列表字段进行比较排序
     */
    public static <T> void sortByField(List<T> dtoList,final String fieldName,String order) {
        int compare=1;
        if ("desc".equals(order)){
            compare=-1;
        }
        final int finalCompare = compare;

        Collections.sort(dtoList, new Comparator<T>() {
            public int compare(T o1, T o2) {
                PropertyDescriptor pd1 = null;
                PropertyDescriptor pd2 = null;
                Object value1 =null;
                Object value2 =null;
                try {
                    pd1 = new PropertyDescriptor(fieldName, o1.getClass());
                    value1 = pd1.getReadMethod().invoke(o1, null);

                    pd2 = new PropertyDescriptor(fieldName, o2.getClass());
                    value2 = pd2.getReadMethod().invoke(o2, null);

                } catch (IntrospectionException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

                 if (value1.getClass().equals(Double.class)){
                    if ((Double)value1 > (Double)value2) {
                        return finalCompare;
                    } else if ((Double)value1 < (Double)value2) {
                        return -finalCompare;
                    }
                }else if (value1.getClass().equals(Integer.class)){
                    if ((Integer)value1 > (Integer)value2) {
                        return finalCompare;
                    } else if ((Integer)value1 < (Integer)value2) {
                        return -finalCompare;
                    }
                }
                return 0;
            }
        });
    }
    
    /**
	 * 获取指定长度(按字节长度获取)的字符串
	 * 
	 * @param src
	 *            源字符串
	 * @param length
	 *            长度
	 * @return
	 */
	public static String getSubStr(String src, int length) {
		if(StringUtils.isEmpty(src)) {
			return null;
		}
		if(src.getBytes().length > length) {
			byte[] b = src.getBytes();
			byte[] s = new byte[length];
			for(int i = 0; i < length; i++) {
				s[i] = b[i];
			}
			return new String(s);
		} else {
			return src;
		}
	}
    
    /**
	 * 获取异常信息内容
	 * 
	 * @param e
	 *            异常对象
	 * @param length
	 *            指定长度
	 * @return 返回异常信息内容
	 */
	public static String getExceptionString(Exception e, int length) {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
//		PrintStream ps = new PrintStream(os);
		String msg = os.toString();
		if(msg.length() > length) {
			msg = getSubStr(msg, length);
		}
		return msg;
	}
	
	/**
	 * 深度拷贝2个对象,包扩关联对象 add by lsw
	 * 
	 * @param srcObj
	 * @throws IOException,
	 *             ClassNotFoundException
	 * 
	 */
	public static Object copyObject(Object srcObj) throws IOException, ClassNotFoundException {
		// 利用对象序列化技术
		ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
		ObjectOutputStream out = new ObjectOutputStream(byteOut);
		out.writeObject(srcObj);
		ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
		ObjectInputStream in = new ObjectInputStream(byteIn);
		return in.readObject();

	}

	/**
	 * 深度拷贝对象,包扩关联对象,返回拷贝数组 add by lsw
	 * 
	 * @param srcObj
	 * @param count
	 *            拷贝个数
	 * @throws IOException,
	 *             ClassNotFoundException
	 * 
	 */
	public static Object[] copyObject(Object srcObj, int count) throws IOException, ClassNotFoundException {
		// 利用对象序列化技术
		ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
		ObjectOutputStream out = new ObjectOutputStream(byteOut);
		out.writeObject(srcObj);
		ByteArrayInputStream byteIn = null;
		ObjectInputStream in = null;
		Object[] retObj = new Object[count];
		for(int i = 0; i < count; i++) {
			byteIn = new ByteArrayInputStream(byteOut.toByteArray());
			in = new ObjectInputStream(byteIn);
			retObj[i] = in.readObject();
		}
		return retObj;
	}
	
	/**
     * 移除list中重复的对象。
     * List中的对象必须依据hashCode的协定正确重写hashCode及equals方法。
     *
     * @param list 数据类型。
     */
    public static <T> void removeDuplicate(List<T> list) {
        Set<T> set = new HashSet<T>(list);
        list.clear();
        list.addAll(set);
    }
    
    /**
     * 根据比较字段对List中的对象进行排序
     *
     * @param <T>
     * @param list
     * @param comparedField  比较字段
     * @param isSortedByDesc 排序方式,true为降序,false为升序
     */
    private static <T> void sort(List<T> list, final String[] orderByFields,
                                 final boolean isSortedByDesc) {
        if(list == null || list.size() == 0) {
            return;
        }
        Comparator<T> comparator = new Comparator<T>() {
            public int compare(T objOne, T objTwo) {
                boolean isMap = false;
                if(orderByFields != null && orderByFields.length > 0) {
                    Class<?> cls = objOne.getClass();
                    if(objOne instanceof Map<?, ?>) {
                        // 比较对象为Map
                        isMap = true;
                    } else {
                        // 比较对象为JavaBean
                        isMap = false;
                    }
                    // 比较对象为JavaBean
                    for(String field : orderByFields) {
                        try {
                            Object beanOne;
                            Object beanTwo;
                            if(isMap) {
                                if(!((Map<?, ?>) objOne).containsKey(field)
                                        || !((Map<?, ?>) objTwo).containsKey(field)) {
                                    // 不存在字段,则抛异常
                                    throw new Exception("对象中不存在比较字段！");
                                }
                                beanOne =((Map<?, ?>) objOne).get(field);
                                beanTwo =((Map<?, ?>) objTwo).get(field);
                            } else {
                            	try {
                            		Field fileOne = cls.getDeclaredField(field);
								} catch (Exception e) {
									cls = cls.getSuperclass();
								}
                                Field fileOne = cls.getDeclaredField(field);
                                fileOne.setAccessible(true);
                                Field fileTwo = cls.getDeclaredField(field);
                                fileTwo.setAccessible(true);
                                beanOne = fileOne.get(objOne);
                                beanTwo = fileTwo.get(objTwo);
                            }
                            if(beanOne == null && beanTwo == null) {
                                // 两个字段值都为空,表示相等,继续比较下一个字段
                                continue;
                            } else if(beanOne == null && beanTwo != null) {
                                // 第一个字段值为空,第二个字段值不为空,返回比较结果大于0(beanOne > beanTwo)
                                if(isSortedByDesc) {
                                    return -1;
                                } else {
                                    return 1;
                                }
                            } else if(beanOne != null && beanTwo == null) {
                                // 第一个字段值不为空,第二个字段值为空,返回比较结果小于0(beanOne < beanTwo)
                                if(isSortedByDesc) {
                                    return 1;
                                } else {
                                    return -1;
                                }
                            } else {
                                // 字段值都转换为字符串进行比较
                                int compareResult = 0;
                                if(beanOne instanceof Date) {
                                    compareResult =((Date) beanOne).compareTo((Date) beanTwo);
                                } else {
                                    compareResult = beanOne.toString().compareTo(beanTwo.toString());
                                }
                                if(compareResult == 0) {
                                    // 两个字段值相等,继续比较下一个字段
                                    continue;
                                } else {
                                    // 排序方式为降序,对比较结果取反
                                    if(isSortedByDesc) {
                                        compareResult = 0 - compareResult;
                                    }
                                    // 两个字段值不相等,返回比较结果
                                    return compareResult;
                                }
                            }
                        } catch(Exception e) {
                            throw new RuntimeException("List排序异常,该排序字段不存在:" + field, e);
                        }
                    }
                } else {
                    // 没有比较字段,两个对象认为是相等的
                    return 0;
                }
                // 前面都没返回,最后认为对象是相等的
                return 0;
            }
        };
        Collections.sort(list, comparator);
    }

    /**
     * 根据比较字段对List中的对象以升序方式进行排序。
     *
     * @param <T>
     * @param list
     * @param orderByField 比较字段
     */
    public static <T> void sortByAsc(List<T> list, String[] orderByFields) {
        sort(list, orderByFields, false);
    }

    /**
     * 根据比较字段对List中的对象以降序方式进行排序。
     *
     * @param <T>
     * @param list
     * @param orderByField
     */
    public static <T> void sortByDesc(List<T> list, String[] orderByFields) {
        sort(list, orderByFields, true);
    }


}